home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util1 / wbs12.lha / WBStartup / WBS.c < prev    next >
C/C++ Source or Header  |  1995-11-25  |  36KB  |  1,146 lines

  1. /*
  2.  * WBStartup - A (small) WBStartup manager
  3.  * Written by Stephan 'Septh' Schreiber
  4.  * Freeware - use at will
  5.  *
  6.  * There's still a lot of work to do,
  7.  * but I'm already quite happy with this.
  8.  * 
  9.  * (BTW: set your tabs to 4 spaces)
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdarg.h>
  15. #include <exec/types.h>
  16. #include <exec/lists.h>
  17. #include <exec/nodes.h>
  18. #include <exec/memory.h>
  19. #include <dos/dos.h>
  20. #include <dos/exall.h>
  21. #include <dos/notify.h>
  22. #include <intuition/intuition.h>
  23. #include <intuition/gadgetclass.h>
  24. #include <graphics/gfxmacros.h>
  25. #include <libraries/gadtools.h>
  26. #include <workbench/workbench.h>
  27.  
  28. #include <clib/exec_protos.h>
  29. #include <clib/dos_protos.h>
  30. #include <clib/utility_protos.h>
  31. #include <clib/intuition_protos.h>
  32. #include <clib/gadtools_protos.h>
  33. #include <clib/graphics_protos.h>
  34. #include <clib/icon_protos.h>
  35. #include <clib/wb_protos.h>
  36.  
  37. #include <pragmas/exec_sysbase_pragmas.h>
  38. #include <pragmas/dos_pragmas.h>
  39. #include <pragmas/utility_pragmas.h>
  40. #include <pragmas/intuition_pragmas.h>
  41. #include <pragmas/gadtools_pragmas.h>
  42. #include <pragmas/graphics_pragmas.h>
  43. #include <pragmas/icon_pragmas.h>
  44. #include <pragmas/wb_pragmas.h>
  45.  
  46. #define    DEBUG    1
  47. #include <debug.h>
  48.  
  49. /*****************************************************************************
  50.  * Macros & constants
  51.  *****************************************************************************/
  52. /* Our default drawers */
  53. #define    ENABLED_DIR        "Sys:WBStartup/WBStartup (Enabled)"
  54. #define    DISABLED_DIR    "Sys:WBStartup/WBStartup (Disabled)"
  55.  
  56. /* Gadgets IDs */
  57. enum
  58. {    GAD_ENABLED_LV,
  59.     GAD_DISABLED_LV,
  60.     GAD_DISABLE_BUTTON,
  61.     GAD_ENABLE_BUTTON,
  62.     GAD_INFO_BUTTON,
  63.     GAD_START_BUTTON,
  64.     GAD_QUIT_BUTTON,
  65. };
  66.  
  67. /* Type des tris */
  68. enum
  69. {    SORT_BY_PRIORITY,
  70.     SORT_BY_NAME,
  71. };
  72.  
  73. /*****************************************************************************
  74.  * Structures & types
  75.  *****************************************************************************/
  76. struct StartupTool
  77. {    struct Node Node;
  78.     UBYTE       Selected;
  79.     UBYTE       StartPri;
  80.     UBYTE       Name[40];
  81. };
  82.  
  83. #define    STF_SELECTED    (1L<<0)
  84.  
  85. /*****************************************************************************
  86.  * Global variables
  87.  *****************************************************************************/
  88. const UBYTE *version = "$VER: WBStartup 1.2 (25.11.95)";
  89.  
  90. extern struct Library   *SysBase;
  91. extern struct Library   *DOSBase;
  92. extern struct WBStartup *_WBenchMsg;
  93.  
  94. struct Library   *UtilityBase;
  95. struct Library   *IntuitionBase;
  96. struct Library   *GadToolsBase;
  97. struct Library   *GfxBase;
  98. struct Library   *WorkbenchBase;
  99. struct Library   *IconBase;
  100.  
  101. struct Screen    *scr;
  102. struct DrawInfo  *dri;
  103. APTR              vi;
  104. struct Gadget    *glist;
  105. struct Gadget    *enabled_lv;
  106. struct Gadget    *enabled_str;
  107. struct Gadget    *disabled_lv;
  108. struct Gadget    *disabled_str;
  109. struct Gadget    *disable_button;
  110. struct Gadget    *enable_button;
  111. struct Gadget    *info_button;
  112. struct Gadget    *start_button;
  113. struct Hook       lv_hook;
  114. struct Window    *win;
  115. struct Requester  req;
  116.  
  117. struct MinList    enabled_list;
  118. LONG              num_enabled;
  119. struct MinList    disabled_list;
  120. LONG              num_disabled;
  121. LONG              sort_type;
  122. LONG              no_icon_position;
  123.  
  124. struct TextAttr topaz8 = { "topaz.font", 8, 0, 0 };
  125. UBYTE enabled_buf[64];
  126. UBYTE disabled_buf[64];
  127. UBYTE enabled_dir[256];
  128. UBYTE disabled_dir[256];
  129. UBYTE win_title[128];
  130.  
  131. /*****************************************************************************
  132.  * Protoypes
  133.  *****************************************************************************/
  134. extern void NewList(struct List *list);
  135.  
  136. /*****************************************************************************
  137.  * Bloque la fenêtre
  138.  *****************************************************************************/
  139. VOID LockWindow(VOID)
  140. {
  141.     InitRequester(&req);
  142.     Request(&req, win);
  143.     SetWindowPointer(win, WA_BusyPointer,  TRUE,
  144.                           WA_PointerDelay, TRUE,
  145.                           TAG_DONE);
  146. }
  147.  
  148. /*****************************************************************************
  149.  * Débloque la fenêtre
  150.  *****************************************************************************/
  151. VOID UnlockWindow(VOID)
  152. {
  153.     EndRequest(&req, win);
  154.     SetWindowPointerA(win, NULL);
  155. }
  156.  
  157. /*****************************************************************************
  158.  * Show up an EasyRequester
  159.  *****************************************************************************/
  160. LONG ShowReq(UBYTE *text, UBYTE *gadgets, ...)
  161. {
  162. static struct EasyStruct es =
  163. {    sizeof(struct EasyStruct), 0L,
  164.     "WBStartup", NULL, NULL,
  165. };
  166. va_list va;
  167. LONG ret;
  168.  
  169.     /* Bloque la fenêtre */
  170.     LockWindow();
  171.  
  172.     /* Affiche le Requester */
  173.     va_start(va, gadgets);
  174.  
  175.     es.es_TextFormat   = text;
  176.     es.es_GadgetFormat = gadgets;
  177.     ret = EasyRequestArgs(win, &es, NULL, (APTR)va);
  178.  
  179.     va_end(va);
  180.  
  181.     /* Débloque la fenêtre */
  182.     UnlockWindow();
  183.  
  184.     return(ret);
  185. }
  186.  
  187. /*****************************************************************************
  188.  * Insert a node in a list, in alphabetic order
  189.  *****************************************************************************/
  190. void AddToolNode(struct List *list, struct Node *node)
  191. {
  192. struct Node *n;
  193.  
  194.     /* Simple security */
  195.     node->ln_Succ = NULL;
  196.     node->ln_Pred = NULL;
  197.  
  198.     switch(sort_type)
  199.     {    case SORT_BY_PRIORITY:
  200.             Enqueue(list, node);
  201.             break;
  202.  
  203.         case SORT_BY_NAME:
  204.             /* Go backwards to the preceeding node */
  205.             n = list->lh_TailPred;
  206.             while (n->ln_Pred && (stricmp(n->ln_Name, node->ln_Name) >= 0))
  207.                 n = n->ln_Pred;
  208.  
  209.             /* Insert the new node after its predecessor */
  210.             Insert(list, node, n);
  211.             break;
  212.     }
  213. }
  214.  
  215. /*****************************************************************************
  216.  * Look for a node, given its ordinal number
  217.  *****************************************************************************/
  218. LONG GetNodeNumber(struct List *list, struct Node *node)
  219. {
  220. register struct Node *n;
  221. LONG number = - 1;
  222.  
  223.     n = list->lh_Head;
  224.     if (n->ln_Succ)
  225.     {    do
  226.         {    number++;
  227.             if (n == node)
  228.                 break;
  229.         } while (n = n->ln_Succ);
  230.     }
  231.  
  232.     return(number);
  233. }
  234.  
  235. /*****************************************************************************
  236.  * Search the Nth node of a list
  237.  *****************************************************************************/
  238. struct Node *GetNode(struct List *list, UWORD number)
  239. {
  240. register struct Node *n;
  241.  
  242.     for (n = list->lh_Head; n->ln_Succ && number ; n = n->ln_Succ, number--)
  243.     { /* Nothing */ }
  244.  
  245.     return(number ? NULL : n);
  246. }
  247.  
  248. /*****************************************************************************
  249.  * Edit a tool's icon
  250.  *****************************************************************************/
  251. VOID EditToolInfo(struct StartupTool *st)
  252. {
  253. struct List *list;
  254. BPTR lock, olddir;
  255. struct NotifyRequest *nr;
  256. LONG signum;
  257. ULONG sig;
  258. UBYTE icon_name[128];
  259. BOOL changed = FALSE;
  260.  
  261.     /* Bloque la fenêtre */
  262.     LockWindow();
  263.  
  264.     list = (struct List *)&enabled_list;
  265.     if (FindName(list, st->Node.ln_Name))
  266.         lock = Lock(enabled_dir, SHARED_LOCK);
  267.     else
  268.     {    list = (struct List *)&disabled_list;
  269.         if (FindName(list, st->Node.ln_Name))
  270.             lock = Lock(disabled_dir, SHARED_LOCK);
  271.         else
  272.             lock = NULL;
  273.     }
  274.  
  275.     if (lock)
  276.     {    olddir = CurrentDir(lock);
  277.  
  278.         if (nr = AllocVec(sizeof(struct NotifyRequest), MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR))
  279.         {    if ((signum = AllocSignal(-1L)) != -1L)
  280.             {    sprintf(icon_name, "%s.info", st->Node.ln_Name);
  281.  
  282.                 nr->nr_Name                         = icon_name;
  283.                 nr->nr_Flags                        = NRF_SEND_SIGNAL;
  284.                 nr->nr_stuff.nr_Signal.nr_Task      = FindTask(NULL);
  285.                 nr->nr_stuff.nr_Signal.nr_SignalNum = signum;
  286.  
  287.                 if (StartNotify(nr))
  288.                 {    WBInfo(lock, st->Node.ln_Name, win->WScreen);
  289.  
  290.                     sig = 1L << signum;
  291.                     if (CheckSignal(sig) & sig)
  292.                         changed = TRUE;
  293.  
  294.                     EndNotify(nr);
  295.                 }
  296.                 FreeSignal(signum);
  297.             }
  298.             FreeVec(nr);
  299.         }
  300.  
  301.         /* Changé ? */
  302.         if (changed)
  303.         {    struct DiskObject *dobj;
  304.             UBYTE *s;
  305.             LONG pri;
  306.             struct Gadget *lv;
  307.             LONG num;
  308.  
  309.             if (dobj = GetDiskObject(st->Node.ln_Name))
  310.             {    if (s = FindToolType(dobj->do_ToolTypes, "STARTPRI"))
  311.                     StrToLong(s, &pri);
  312.                 else
  313.                     pri = 0;
  314.  
  315.                 if (pri != st->Node.ln_Pri)
  316.                 {    lv = ((list == (struct List *)&enabled_list) ? enabled_lv : disabled_lv);
  317.  
  318.                     GT_SetGadgetAttrs(lv, win, NULL, GTLV_Labels, -1L, TAG_DONE);
  319.  
  320.                     Remove((struct Node *)st);
  321.                     st->Node.ln_Pri = pri;
  322.                     AddToolNode(list, (struct Node *)st);
  323.                     num = GetNodeNumber(list, (struct Node *)st);
  324.  
  325.                     GT_SetGadgetAttrs(lv, win, NULL, GTLV_Labels,      list,
  326.                                                      GTLV_Selected,    num,
  327.                                                      GTLV_MakeVisible, num,
  328.                                                      TAG_DONE);
  329.                 }
  330.                 FreeDiskObject(dobj);
  331.             }
  332.         }
  333.  
  334.         CurrentDir(olddir);
  335.         UnLock(lock);
  336.     }
  337.  
  338.     /* Débloque la fenêtre */
  339.     UnlockWindow();
  340. }
  341.  
  342. /*****************************************************************************
  343.  * Move a file and its icon
  344.  *****************************************************************************/
  345. BOOL MoveTool(struct StartupTool *st, UBYTE *from_dir, UBYTE *to_dir)
  346. {
  347. BPTR from_lock, to_lock;
  348. UBYTE from_name[256], to_name[256], cmd[1024];
  349. struct DiskObject *dobj;
  350. BOOL ok = FALSE;
  351.  
  352.     if (st)
  353.     {    if (from_lock = Lock(from_dir, SHARED_LOCK))
  354.         {    if (to_lock = Lock(to_dir, SHARED_LOCK))
  355.             {    /* Build source name */
  356.                 strcpy(from_name, from_dir);
  357.                 AddPart(from_name, st->Node.ln_Name, sizeof(from_name));
  358.  
  359.                 /* Build destination name */
  360.                 strcpy(to_name, to_dir);
  361.                 AddPart(to_name, st->Node.ln_Name, sizeof(to_name));
  362.  
  363.                 /* Are both file on the save volume? */
  364.                 switch (SameLock(from_lock, to_lock))
  365.                 {    case LOCK_SAME:
  366.                         /* !?! */
  367.                         break;
  368.  
  369.                     case LOCK_SAME_VOLUME:
  370.                         /* Rename SOURCE as DEST */
  371.                         Rename(from_name, to_name);
  372.  
  373.                         /* Also move the icon */
  374.                         if (dobj = GetDiskObject(from_name))
  375.                         {    DeleteDiskObject(from_name);
  376.  
  377.                             if (no_icon_position)
  378.                                 dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION;
  379.  
  380.                             PutDiskObject(to_name, dobj);
  381.  
  382.                             FreeDiskObject(dobj);
  383.  
  384.                             /* Done */
  385.                             ok = TRUE;
  386.                         }
  387.                         else ShowReq("Can't write icon for\n'%s'\nDos Error %ld", to_name, IoErr());
  388.                         break;
  389.  
  390.                     case LOCK_DIFFERENT:
  391.                         /* Copy SOURCE to DEST */
  392.                         sprintf(cmd, "c:copy <>NIL: FROM %s TO %s CLONE NOREQ", from_name, to_name);
  393.                         SystemTagList(cmd, NULL);
  394.  
  395.                         /* Delete the original source file */
  396.                         DeleteFile(from_name);
  397.  
  398.                         /* Also move the icon */
  399.                         if (dobj = GetDiskObject(from_name))
  400.                         {    DeleteDiskObject(from_name);
  401.  
  402.                             if (no_icon_position)
  403.                                 dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION;
  404.  
  405.                             PutDiskObject(to_name, dobj);
  406.  
  407.                             FreeDiskObject(dobj);
  408.  
  409.                             /* Done */
  410.                             ok = TRUE;
  411.                         }
  412.                         else ShowReq("Can't write icon for\n'%s'\nDos Error %ld", to_name, IoErr());
  413.                         break;
  414.                 }
  415.                 UnLock(to_lock);
  416.             }
  417.             UnLock(from_lock);
  418.         }
  419.     }
  420.     return(ok);
  421. }
  422.  
  423. /*****************************************************************************
  424.  * Disable a tool (ie. move it from enabled_dir to disabled_dir)
  425.  *****************************************************************************/
  426. VOID DisableTool(struct StartupTool *st)
  427. {
  428.     /* First move the executable and its icon */
  429.     if (MoveTool(st, enabled_dir, disabled_dir))
  430.     {    GT_SetGadgetAttrs(enabled_lv,  win, NULL, GTLV_Labels, ~0L, TAG_DONE);
  431.         GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
  432.  
  433.         /* Remove the tool from its list */
  434.         Remove((struct Node *)st);
  435.         num_enabled--;
  436.  
  437.         /* And put it in the other list */
  438.         AddToolNode((struct List *)&disabled_list, (struct Node *)st);
  439.         num_disabled++;
  440.  
  441.         /* Update the gadgets */
  442.         sprintf(enabled_buf,  "%ld enabled items",  num_enabled);
  443.         sprintf(disabled_buf, "%ld disabled items", num_disabled);
  444.  
  445.         GT_SetGadgetAttrs(enabled_lv,     win, NULL, GTLV_Labels,      &enabled_list,
  446.                                                      GTLV_Selected,    ~0L,
  447.                                                      TAG_DONE);
  448.  
  449.         GT_SetGadgetAttrs(disabled_lv,    win, NULL, GTLV_Labels,      &disabled_list,
  450.                                                      GTLV_Selected,    ~0L,
  451.                                                      GTLV_MakeVisible, GetNodeNumber((struct List *)&disabled_list, (struct Node *)st),
  452.                                                      TAG_DONE);
  453.  
  454.         GT_SetGadgetAttrs(enabled_str,    win, NULL, GTTX_Text,   &enabled_buf[0],  TAG_DONE);
  455.         GT_SetGadgetAttrs(disabled_str,   win, NULL, GTTX_Text,   &disabled_buf[0], TAG_DONE);
  456.         GT_SetGadgetAttrs(enable_button,  win, NULL, GA_Disabled, TRUE, TAG_DONE);
  457.         GT_SetGadgetAttrs(disable_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
  458.         GT_SetGadgetAttrs(info_button,    win, NULL, GA_Disabled, TRUE, TAG_DONE);
  459.         //GT_SetGadgetAttrs(start_button,   win, NULL, GA_Disabled, TRUE, TAG_DONE);
  460.     }
  461. }
  462.  
  463. /*****************************************************************************
  464.  * Enable a tool (ie. move it from disabled_dir to enabled_dir)
  465.  *****************************************************************************/
  466. VOID EnableTool(struct StartupTool *st)
  467. {
  468.     if (MoveTool(st, disabled_dir, enabled_dir))
  469.     {    GT_SetGadgetAttrs(enabled_lv,  win, NULL, GTLV_Labels, ~0L, TAG_DONE);
  470.         GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
  471.  
  472.         /* Remove the tool from its list */
  473.         Remove((struct Node *)st);
  474.         num_disabled--;
  475.  
  476.         /* And put it in the other list */
  477.         AddToolNode((struct List *)&enabled_list, (struct Node *)st);
  478.         num_enabled++;
  479.  
  480.         /* Update the gadgets */
  481.         sprintf(enabled_buf,  "%ld enabled items",  num_enabled);
  482.         sprintf(disabled_buf, "%ld disabled items", num_disabled);
  483.  
  484.         GT_SetGadgetAttrs(enabled_lv,     win, NULL, GTLV_Labels,      &enabled_list,
  485.                                                      GTLV_Selected,    ~0L,
  486.                                                      GTLV_MakeVisible, GetNodeNumber((struct List *)&enabled_list, (struct Node *)st),
  487.                                                      TAG_DONE);
  488.  
  489.         GT_SetGadgetAttrs(disabled_lv,    win, NULL, GTLV_Labels,   &disabled_list,
  490.                                                      GTLV_Selected, ~0L,
  491.                                                      TAG_DONE);
  492.  
  493.         GT_SetGadgetAttrs(enabled_str,    win, NULL, GTTX_Text,   &enabled_buf[0],  TAG_DONE);
  494.         GT_SetGadgetAttrs(disabled_str,   win, NULL, GTTX_Text,   &disabled_buf[0], TAG_DONE);
  495.         GT_SetGadgetAttrs(enable_button,  win, NULL, GA_Disabled, TRUE, TAG_DONE);
  496.         GT_SetGadgetAttrs(disable_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
  497.         GT_SetGadgetAttrs(info_button,    win, NULL, GA_Disabled, TRUE, TAG_DONE);
  498.         //GT_SetGadgetAttrs(start_button,   win, NULL, GA_Disabled, TRUE, TAG_DONE);
  499.     }
  500. }
  501.  
  502. /*****************************************************************************
  503.  * Main event loop
  504.  *****************************************************************************/
  505. VOID MainLoop(VOID)
  506. {
  507. UWORD esel, dsel;
  508. ULONG secs, mics;
  509. struct StartupTool *st;
  510. BOOL fini;
  511. struct IntuiMessage *imsg, im;
  512.  
  513.     esel = (UWORD)~0;
  514.     dsel = (UWORD)~0;
  515.     secs = 0L;
  516.     mics = 0L;
  517.     st   = NULL;
  518.     fini = FALSE;
  519.     do
  520.     {    WaitPort(win->UserPort);
  521.         while (imsg = GT_GetIMsg(win->UserPort))
  522.         {    im = *imsg;
  523.             GT_ReplyIMsg(imsg);
  524.             imsg = &im;
  525.  
  526.             switch(imsg->Class)
  527.             {    case IDCMP_CLOSEWINDOW:
  528.                     fini = TRUE;
  529.                     break;
  530.  
  531.                 case IDCMP_REFRESHWINDOW:
  532.                     GT_BeginRefresh(win);
  533.                     GT_EndRefresh(win, TRUE);
  534.                     break;
  535.  
  536.                 case IDCMP_VANILLAKEY:
  537.                     if (imsg->Code == 27)
  538.                         fini = TRUE;
  539.                     break;
  540.  
  541.                 case IDCMP_GADGETUP:
  542.                     switch(((struct Gadget *)imsg->IAddress)->GadgetID)
  543.                     {    case GAD_ENABLED_LV:
  544.                             if ((esel == imsg->Code) && DoubleClick(secs, mics, imsg->Seconds, imsg->Micros))
  545.                             {    /* Edit tooltypes on double-click */
  546.                                 EditToolInfo(st);
  547.                                 esel = GetNodeNumber((struct List *)&enabled_list, (struct Node *)st);
  548.                             }
  549.                             else
  550.                             {    esel = imsg->Code;
  551.                                 dsel = (UWORD)~0;
  552.                                 secs = imsg->Seconds;
  553.                                 mics = imsg->Micros;
  554.  
  555.                                 st = (struct StartupTool *)GetNode((struct List *)&enabled_list, esel);
  556.  
  557.                                 /* Update the gadgets */
  558.                                 GT_SetGadgetAttrs(disabled_lv,    win, NULL, GTLV_Selected, ~0,    TAG_DONE);
  559.                                 GT_SetGadgetAttrs(enable_button,  win, NULL, GA_Disabled,   TRUE,  TAG_DONE);
  560.                                 GT_SetGadgetAttrs(disable_button, win, NULL, GA_Disabled,   FALSE, TAG_DONE);
  561.                                 GT_SetGadgetAttrs(info_button,    win, NULL, GA_Disabled,   FALSE, TAG_DONE);
  562.                                 //GT_SetGadgetAttrs(start_button,   win, NULL, GA_Disabled,   TRUE,  TAG_DONE);
  563.                             }
  564.                             break;
  565.  
  566.                         case GAD_DISABLED_LV:
  567.                             if ((dsel == imsg->Code) && DoubleClick(secs, mics, imsg->Seconds, imsg->Micros))
  568.                             {    /* Edit tooltypes on double-click -- not implemented */
  569.                                 EditToolInfo(st);
  570.                                 dsel = GetNodeNumber((struct List *)&disabled_list, (struct Node *)st);
  571.                             }
  572.                             else
  573.                             {    esel = (UWORD)~0;
  574.                                 dsel = imsg->Code;
  575.                                 secs = imsg->Seconds;
  576.                                 mics = imsg->Micros;
  577.  
  578.                                 st = (struct StartupTool *)GetNode((struct List *)&disabled_list, dsel);
  579.  
  580.                                 /* Update the gadgets */
  581.                                 GT_SetGadgetAttrs(enabled_lv,     win, NULL, GTLV_Selected, ~0,    TAG_DONE);
  582.                                 GT_SetGadgetAttrs(enable_button,  win, NULL, GA_Disabled,   FALSE, TAG_DONE);
  583.                                 GT_SetGadgetAttrs(disable_button, win, NULL, GA_Disabled,   TRUE,  TAG_DONE);
  584.                                 GT_SetGadgetAttrs(info_button,    win, NULL, GA_Disabled,   FALSE, TAG_DONE);
  585.                                 //GT_SetGadgetAttrs(start_button,   win, NULL, GA_Disabled,   FALSE, TAG_DONE);
  586.                             }
  587.                             break;
  588.  
  589.                         case GAD_DISABLE_BUTTON:
  590.                             DisableTool(st);
  591.                             st = NULL;
  592.                             break;
  593.  
  594.                         case GAD_ENABLE_BUTTON:
  595.                             EnableTool(st);
  596.                             st = NULL;
  597.                             break;
  598.  
  599.                         case GAD_START_BUTTON:
  600.                             /* Start the tool -- not implemented */
  601.                             break;
  602.  
  603.                         case GAD_INFO_BUTTON:
  604.                             /* Edit the tool's icon */
  605.                             EditToolInfo(st);
  606.  
  607.                             if (esel != (UWORD)~0)
  608.                                 esel = GetNodeNumber((struct List *)&enabled_list, (struct Node *)st);
  609.                             else
  610.                                 dsel = GetNodeNumber((struct List *)&disabled_list, (struct Node *)st);
  611.                             break;
  612.  
  613.                         case GAD_QUIT_BUTTON:
  614.                             fini = TRUE;
  615.                             break;
  616.                     }
  617.                     break;
  618.             }
  619.         }
  620.     } while (!fini);
  621. }
  622.  
  623. /*****************************************************************************
  624.  * The GTLV_CallBack hook
  625.  *****************************************************************************/
  626. ULONG __asm __saveds GTLVCallBack(register __a0 struct Hook *hook,
  627.                                   register __a2 struct StartupTool *st,
  628.                                   register __a1 struct LVDrawMsg *lvdmsg)
  629. {
  630. static UWORD ghost_pattern[] = { 0x4444, 0x1111 };
  631. UBYTE pri[10];
  632. LONG apen, bpen, pl, pw, w, h, dy, len;
  633. struct TextExtent te;
  634.  
  635.     if (lvdmsg->lvdm_MethodID == LV_DRAW)
  636.     {    switch(lvdmsg->lvdm_State)
  637.         {    case LVR_NORMAL:
  638.             case LVR_NORMALDISABLED:
  639.                 apen = lvdmsg->lvdm_DrawInfo->dri_Pens[TEXTPEN];
  640.                 bpen = lvdmsg->lvdm_DrawInfo->dri_Pens[BACKGROUNDPEN];
  641.                 break;
  642.  
  643.             case LVR_SELECTED:
  644.             case LVR_SELECTEDDISABLED:
  645.                 apen = lvdmsg->lvdm_DrawInfo->dri_Pens[FILLTEXTPEN];
  646.                 bpen = lvdmsg->lvdm_DrawInfo->dri_Pens[FILLPEN];
  647.                 break;
  648.         }
  649.  
  650.         /* Efface le fond */
  651.         SetAPen(lvdmsg->lvdm_RastPort, bpen);
  652.         RectFill(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_Bounds.MinX, lvdmsg->lvdm_Bounds.MinY,
  653.                                         lvdmsg->lvdm_Bounds.MaxX, lvdmsg->lvdm_Bounds.MaxY);
  654.  
  655.         /* Calcule la largeur de la priorité */
  656.         pl = sprintf(pri, "%ld", st->Node.ln_Pri);
  657.         pw = TextLength(lvdmsg->lvdm_RastPort, pri, pl);
  658.  
  659.         /* Calcule la largeur de la ligne */
  660.         w = (UWORD)((lvdmsg->lvdm_Bounds.MaxX - lvdmsg->lvdm_Bounds.MinX + 1) - pw - 8);
  661.  
  662.         /* Calcule la hauteur totale de la ligne */
  663.         h = (UWORD)(lvdmsg->lvdm_Bounds.MaxY - lvdmsg->lvdm_Bounds.MinY + 1);
  664.  
  665.         /* Centre la ligne verticalement */
  666.         dy = (UWORD)(((h - lvdmsg->lvdm_RastPort->Font->tf_YSize) / 2) + lvdmsg->lvdm_RastPort->Font->tf_Baseline);
  667.  
  668.         /* Trouve le nombre maximum de caractères à dessiner */
  669.         len = TextFit(lvdmsg->lvdm_RastPort, st->Node.ln_Name, strlen(st->Node.ln_Name), &te, NULL, 1L, w, h);
  670.  
  671.         /* Dessine le texte */
  672.         SetAPen(lvdmsg->lvdm_RastPort, apen);
  673.         SetDrMd(lvdmsg->lvdm_RastPort, JAM1);
  674.  
  675.         Move(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_Bounds.MinX + 4, lvdmsg->lvdm_Bounds.MinY + dy);
  676.         Text(lvdmsg->lvdm_RastPort, st->Node.ln_Name, len);
  677.  
  678.         /* Dessine le texte de la priorité */
  679.         Move(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_Bounds.MaxX - pw - 4, lvdmsg->lvdm_Bounds.MinY + dy);
  680.         Text(lvdmsg->lvdm_RastPort, pri, pl);
  681.  
  682.         /* Le gadget est inhibé? */
  683.         if ((lvdmsg->lvdm_State == LVR_NORMALDISABLED) || (lvdmsg->lvdm_State == LVR_SELECTEDDISABLED))
  684.         {    SetAPen(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_DrawInfo->dri_Pens[BLOCKPEN]);
  685.             SetAfPt(lvdmsg->lvdm_RastPort, ghost_pattern, 1L);
  686.             RectFill(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_Bounds.MinX, lvdmsg->lvdm_Bounds.MinY,
  687.                                             lvdmsg->lvdm_Bounds.MaxX, lvdmsg->lvdm_Bounds.MaxY);
  688.             SetAfPt(lvdmsg->lvdm_RastPort, NULL, 0);
  689.         }
  690.  
  691.         return(LVCB_OK);
  692.     }
  693.  
  694.     return(LVCB_UNKNOWN);
  695. }
  696.  
  697. /*****************************************************************************
  698.  * Create the gadgets - no font sensitivity, use old good Topaz/8...
  699.  *****************************************************************************/
  700. BOOL CreateGadgets(VOID)
  701. {
  702. struct NewGadget ng;
  703. struct Gadget *g;
  704. WORD ox, oy;
  705. BOOL ok = FALSE;
  706.  
  707.     glist = NULL;
  708.     if (g = CreateContext(&glist))
  709.     {    ox = scr->WBorLeft + 5;
  710.         oy = scr->BarHeight + 1 + 20;
  711.  
  712.         lv_hook.h_Entry    = (ULONG (*)())GTLVCallBack;
  713.         lv_hook.h_SubEntry = NULL;
  714.         lv_hook.h_Data     = NULL;
  715.  
  716.         /* ListView 'enabled' */
  717.         ng.ng_LeftEdge   = ox;
  718.         ng.ng_TopEdge    = oy;
  719.         ng.ng_Width      = 250;
  720.         ng.ng_Height     = 130;
  721.         ng.ng_GadgetText = "Enabled Tools";
  722.         ng.ng_TextAttr   = &topaz8;
  723.         ng.ng_GadgetID   = GAD_ENABLED_LV;
  724.         ng.ng_Flags      = PLACETEXT_ABOVE|NG_HIGHLABEL;
  725.         ng.ng_VisualInfo = vi;
  726.         ng.ng_UserData   = NULL;
  727.         g = enabled_lv  = CreateGadget(LISTVIEW_KIND, g, &ng, GTLV_ShowSelected, NULL,
  728.                                                               GTLV_CallBack,    &lv_hook,
  729.                                                               GT_Underscore,     '_',
  730.                                                               LAYOUTA_Spacing,   2L,
  731.                                                               TAG_DONE);
  732.  
  733.         ng.ng_TopEdge   += 130;
  734.         ng.ng_Height     = 14;
  735.         ng.ng_GadgetText = NULL;
  736.         g = enabled_str = CreateGadget(TEXT_KIND, g, &ng, GTTX_Border, TRUE,
  737.                                                           TAG_DONE);
  738.  
  739.         /* ListView 'disabled' */
  740.         ng.ng_LeftEdge  += 360;
  741.         ng.ng_TopEdge    = oy;
  742.         ng.ng_Height     = 130;
  743.         ng.ng_GadgetText = "Disabled Tools";
  744.         ng.ng_GadgetID   = GAD_DISABLED_LV;
  745.         g = disabled_lv = CreateGadget(LISTVIEW_KIND, g, &ng, GTLV_ShowSelected, NULL,
  746.                                                               GTLV_CallBack,    &lv_hook,
  747.                                                               GT_Underscore,     '_',
  748.                                                               LAYOUTA_Spacing,   2L,
  749.                                                               TAG_DONE);
  750.  
  751.         ng.ng_TopEdge   += 130;
  752.         ng.ng_Height     = 14;
  753.         ng.ng_GadgetText = NULL;
  754.         g = disabled_str = CreateGadget(TEXT_KIND, g, &ng, GTTX_Border, TRUE,
  755.                                                            TAG_DONE);
  756.  
  757.         /* Bouton 'Disable ->' */
  758.         ng.ng_LeftEdge   = ox + 260;
  759.         ng.ng_TopEdge    = oy;
  760.         ng.ng_Width      = 90;
  761.         ng.ng_Height     = 14;
  762.         ng.ng_GadgetText = "_Disable ->";
  763.         ng.ng_GadgetID   = GAD_DISABLE_BUTTON;
  764.         ng.ng_Flags      = PLACETEXT_IN;
  765.         g = disable_button = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
  766.                                                                GA_Disabled,   TRUE,
  767.                                                                TAG_DONE);
  768.  
  769.         /* Bouton '<- Enable' */
  770.         ng.ng_TopEdge   += 20;
  771.         ng.ng_GadgetText = "<- _Enable";
  772.         ng.ng_GadgetID   = GAD_ENABLE_BUTTON;
  773.         g = enable_button = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
  774.                                                               GA_Disabled,   TRUE,
  775.                                                               TAG_DONE);
  776.  
  777.         /* Bouton 'Info...' */
  778.         ng.ng_TopEdge   += 20;
  779.         ng.ng_GadgetText = "_Info...";
  780.         ng.ng_GadgetID   = GAD_INFO_BUTTON;
  781.         g = info_button = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
  782.                                                             GA_Disabled,   TRUE,
  783.                                                             TAG_DONE);
  784.  
  785.         /* Bouton 'Start' */
  786.         ng.ng_TopEdge   += 20;
  787.         ng.ng_GadgetText = "_Start";
  788.         ng.ng_GadgetID   = GAD_START_BUTTON;
  789.         g = start_button = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
  790.                                                              GA_Disabled,   TRUE,
  791.                                                              TAG_DONE);
  792.  
  793.         /* Bouton 'Quit' */
  794.         ng.ng_TopEdge    = oy + 130;
  795.         ng.ng_GadgetText = "_Quit";
  796.         ng.ng_GadgetID   = GAD_QUIT_BUTTON;
  797.         g = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
  798.                                               TAG_DONE);
  799.  
  800.         /* Ok ? */
  801.         if (g)
  802.             ok = TRUE;
  803.     }
  804.  
  805.     /* Retourne TRUE ou FALSE */
  806.     return(ok);
  807. }
  808.  
  809. /*****************************************************************************
  810.  * Free a list of tools
  811.  *****************************************************************************/
  812. VOID FreeTools(struct List *list)
  813. {
  814. struct StartupTool *st;
  815.  
  816.     while (st = (struct StartupTool *)RemTail(list))
  817.         FreeVec(st);
  818. }
  819.  
  820. /*****************************************************************************
  821.  * Scan a directory of tools
  822.  *****************************************************************************/
  823. LONG ScanTools(UBYTE *path, struct List *list)
  824. {
  825. BPTR lock, olddir;
  826. UBYTE pat[32];
  827. struct ExAllControl *eac;
  828. struct ExAllData *ead;
  829. BOOL more;
  830. UBYTE eadata[1024], name[128], *s;
  831. struct DiskObject *dobj;
  832. struct StartupTool *st;
  833. LONG pri, num = -1;
  834.  
  835.     sprintf(win_title, "Scanning '%s'...", path);
  836.     SetWindowTitles(win, win_title, (UBYTE *)-1L);
  837.  
  838.     if ((lock = Lock(path, SHARED_LOCK)) == NULL)
  839.     {    if (IoErr() == ERROR_OBJECT_NOT_FOUND)
  840.         {    switch(ShowReq("Directory '%s'\ndoes not exist.\nDo you want to create it?", "Yes|No", path))
  841.             {    case 1:    // Yes
  842.                     if (lock = CreateDir(path))
  843.                     {    /* Add an icon, the same as 'Sys:WBStartup' (if possible) */
  844.                         if (dobj = GetDiskObjectNew("Sys:WBStartup"))
  845.                         {    if (dobj->do_Type != WBDRAWER)
  846.                             {    FreeDiskObject(dobj);
  847.                                 dobj = GetDefDiskObject(WBDRAWER);
  848.                             }
  849.  
  850.                             if (dobj)
  851.                             {    dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION;
  852.  
  853.                                 PutDiskObject(path, dobj);
  854.                                 FreeDiskObject(dobj);
  855.                             }
  856.                             else ShowReq("Can't create icon for\n'%s'\n", "Continue", path);
  857.                         }
  858.                         else ShowReq("Can't create icon for\n'%s'\n", "Continue", path);
  859.                     }
  860.                     else ShowReq("Can't create directory\n'%s'\nDos Error %ld\n", "Cancel", path, IoErr());
  861.                     break;
  862.  
  863.                 case 0:    // No
  864.                     break;
  865.             }
  866.         }
  867.         else ShowReq("Can't access directory\n'%s'\nDos Error %ld\n", "Cancel", path, IoErr());
  868.     }
  869.  
  870.     if (lock)
  871.     {    olddir = CurrentDir(lock);
  872.  
  873.         /* Parse our pattern */
  874.         ParsePatternNoCase("#?.info", pat, sizeof(pat));
  875.  
  876.         if (eac = AllocDosObject(DOS_EXALLCONTROL, NULL))
  877.         {    eac->eac_LastKey     = NULL;
  878.             eac->eac_MatchString = pat;
  879.             eac->eac_MatchFunc   = NULL;
  880.  
  881.             num = 0;
  882.  
  883.             do
  884.             {    more = ExAll(lock, (struct ExAllData *)eadata, sizeof(eadata), ED_NAME, eac);
  885.  
  886.                 if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  887.                 {    /* Erreur */
  888.                     break;
  889.                 }
  890.  
  891.                 if (eac->eac_Entries == 0)
  892.                 {    /* Fin normale, mais pas d'entrées */
  893.                     continue;
  894.                 }
  895.  
  896.                 /* Ajoute la ou les entrées */
  897.                 ead = (struct ExAllData *)eadata;
  898.                 do
  899.                 {    /* Copie le nom, sans le '.info' */
  900.                     s = stpcpy(name, ead->ed_Name);    // stpcpy() retourne la FIN de la chaîne
  901.                     s[-5] = '\0';
  902.  
  903.                     /* Lit l'icône */
  904.                     if (dobj = GetDiskObject(name))
  905.                     {    /* Est-ce un OUTIL ou un PROJET ? */
  906.                         if ((dobj->do_Type == WBTOOL) || (dobj->do_Type == WBPROJECT))
  907.                         {    /* Ajoute un noeud à la liste */
  908.                             if (st = AllocVec(sizeof(struct StartupTool), MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR))
  909.                             {    st->Node.ln_Name = &st->Name[0];
  910.                                 strcpy(st->Node.ln_Name, name);
  911.  
  912.                                 /* Trouve la priorité */
  913.                                 if ((s = FindToolType(dobj->do_ToolTypes, "STARTPRI")) && StrToLong(s, &pri))
  914.                                     st->Node.ln_Pri = pri;
  915.  
  916.                                 AddToolNode(list, (struct Node *)st);
  917.  
  918.                                 num++;
  919.                             }
  920.                         }
  921.                         FreeDiskObject(dobj);
  922.                     }
  923.  
  924.                     /* Passe à l'entrée suivante */
  925.                     ead = ead->ed_Next;
  926.                 } while (ead);
  927.             } while (more);
  928.  
  929.             FreeDosObject(DOS_EXALLCONTROL, eac);
  930.         }
  931.         CurrentDir(olddir);
  932.         UnLock(lock);
  933.     }
  934.  
  935.     /* Return the number of tools read, or -1 on error */
  936.     return(num);
  937. }
  938.  
  939. /*****************************************************************************
  940.  * Get the arguments
  941.  *****************************************************************************/
  942. #define    TEMPLATE    "ENABLED_DIR/K,DISABLED_DIR/K,SORT/K,NO_ICON_POSITION/S"
  943. enum
  944. {    OPT_ENABLED_DIR,
  945.     OPT_DISABLED_DIR,
  946.     OPT_SORT,
  947.     OPT_NO_ICON_POSITION,
  948.     NUM_OPTS
  949. };
  950.  
  951. BOOL GetArgs(VOID)
  952. {
  953. BOOL ok = TRUE;
  954.  
  955.     /* Set the defaults */
  956.     strcpy(enabled_dir,  ENABLED_DIR);
  957.     strcpy(disabled_dir, DISABLED_DIR);
  958.     sort_type = SORT_BY_PRIORITY;
  959.     no_icon_position = FALSE;
  960.  
  961.     if (_WBenchMsg)
  962.     {    BPTR olddir;
  963.         struct DiskObject *dobj;
  964.         UBYTE *s;
  965.  
  966.         olddir = CurrentDir(_WBenchMsg->sm_ArgList->wa_Lock);
  967.  
  968.         /* Read our ToolTypes */
  969.         if (dobj = GetDiskObject(_WBenchMsg->sm_ArgList->wa_Name))
  970.         {    if (s = FindToolType(dobj->do_ToolTypes, "ENABLED_DIR"))
  971.                 strcpy(enabled_dir, s);
  972.  
  973.             if (s = FindToolType(dobj->do_ToolTypes, "DISABLED_DIR"))
  974.                 strcpy(disabled_dir, s);
  975.  
  976.             if (s = FindToolType(dobj->do_ToolTypes, "SORT"))
  977.             {    if (MatchToolValue(s, "PRIORITY"))
  978.                     sort_type = SORT_BY_PRIORITY;
  979.                 else if (MatchToolValue(s, "NAME"))
  980.                     sort_type = SORT_BY_NAME;
  981.             }
  982.  
  983.             if (s = FindToolType(dobj->do_ToolTypes, "NO_ICON_POSITION"))
  984.                 no_icon_position = TRUE;
  985.  
  986.             FreeDiskObject(dobj);
  987.         }
  988.         CurrentDir(olddir);
  989.     }
  990.     else
  991.     {    ULONG opts[NUM_OPTS];
  992.         struct RDArgs *rda;
  993.  
  994.         memset(opts, 0, sizeof(opts));
  995.         rda = ReadArgs(TEMPLATE, opts, NULL);
  996.  
  997.         /* Check for Ctrl-C break */
  998.         if (CheckSignal(SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  999.         {    if (rda)
  1000.             {    FreeArgs(rda);
  1001.                 rda = NULL;
  1002.             }
  1003.             SetIoErr(ERROR_BREAK);
  1004.             ok = FALSE;        // Tell caller to quit
  1005.         }
  1006.  
  1007.         if (rda)
  1008.         {    if (opts[OPT_ENABLED_DIR])
  1009.                 strcpy(enabled_dir, (UBYTE *)opts[OPT_ENABLED_DIR]);
  1010.  
  1011.             if (opts[OPT_DISABLED_DIR])
  1012.                 strcpy(disabled_dir, (UBYTE *)opts[OPT_DISABLED_DIR]);
  1013.  
  1014.             if (opts[OPT_SORT])
  1015.             {    if (stricmp((UBYTE *)opts[OPT_SORT], "PRIORITY"))
  1016.                     sort_type = SORT_BY_PRIORITY;
  1017.                 else if (stricmp((UBYTE *)opts[OPT_SORT], "NAME"))
  1018.                     sort_type = SORT_BY_NAME;
  1019.             }
  1020.  
  1021.             if (opts[OPT_NO_ICON_POSITION])
  1022.                 no_icon_position = TRUE;
  1023.  
  1024.             FreeArgs(rda);
  1025.         }
  1026.         else PrintFault(IoErr(), NULL);
  1027.     }
  1028.  
  1029.     /* Return FALSE if Ctrl-C was hit during ReadArgs() */
  1030.     return(ok);
  1031. }
  1032.  
  1033. /*****************************************************************************
  1034.  * Program entry point
  1035.  *****************************************************************************/
  1036. void main(void)
  1037. {
  1038. struct IBox zoom;
  1039.  
  1040.     /* Open the used libraries */
  1041.     if (UtilityBase = OpenLibrary("utility.library", 39L))
  1042.     {    if (IntuitionBase = OpenLibrary("intuition.library", 39L))
  1043.         {    if (GadToolsBase = OpenLibrary("gadtools.library", 39L))
  1044.             {    if (GfxBase = OpenLibrary("graphics.library", 39L))
  1045.                 {    if (WorkbenchBase = OpenLibrary("workbench.library", 39L))
  1046.                     {    if (IconBase = OpenLibrary("icon.library", 39L))
  1047.                         {    /* Read the arguments, stop if Ctrl-C is hit */
  1048.                             if (GetArgs())
  1049.                             {    /* Open the window */
  1050.                                 if ((scr = LockPubScreen("FRONTPUBSCREEN")) == NULL)
  1051.                                     scr = LockPubScreen(NULL);
  1052.                                 if (scr)
  1053.                                 {    if (dri = GetScreenDrawInfo(scr))
  1054.                                     {    if (vi = GetVisualInfoA(scr, NULL))
  1055.                                         {    if (CreateGadgets())
  1056.                                             {    /* Setup our alternate window position */
  1057.                                                 zoom.Left   = -1;
  1058.                                                 zoom.Top    = -1;
  1059.                                                 zoom.Width  = 150;
  1060.                                                 zoom.Height = scr->BarHeight + 1;
  1061.  
  1062.                                                 if (win = OpenWindowTags(NULL, WA_Left,         0,
  1063.                                                                                WA_Top,          scr->BarHeight + 1,
  1064.                                                                                WA_InnerWidth,   620L,
  1065.                                                                                WA_InnerHeight,  169L,
  1066.                                                                                WA_AutoAdjust,   TRUE,
  1067.                                                                                WA_MinWidth,     zoom.Width,
  1068.                                                                                WA_MinHeight,    zoom.Height,
  1069.                                                                                WA_Zoom,        &zoom,
  1070.                                                                                WA_Flags,        WFLG_CLOSEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|
  1071.                                                                                                 WFLG_SIMPLE_REFRESH|
  1072.                                                                                                 WFLG_RMBTRAP|WFLG_NEWLOOKMENUS|WFLG_ACTIVATE,
  1073.                                                                                WA_IDCMP,        IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
  1074.                                                                                                 IDCMP_VANILLAKEY|
  1075.                                                                                                 LISTVIEWIDCMP|BUTTONIDCMP,
  1076.                                                                                WA_PubScreen,    scr,
  1077.                                                                                WA_Title,        "WBStartup",
  1078.                                                                                WA_ScreenTitle,  "WBStartup - ©1995 by RingarSoft, Inc.",
  1079.                                                                                WA_Gadgets,      glist,
  1080.                                                                                WA_BusyPointer,  TRUE,
  1081.                                                                                WA_PointerDelay, TRUE,
  1082.                                                                                TAG_DONE))
  1083.                                                 {    GT_RefreshWindow(win, NULL);
  1084.  
  1085.                                                     /* Initialize our lists */
  1086.                                                     NewList((struct List *)&enabled_list);
  1087.                                                     NewList((struct List *)&disabled_list);
  1088.  
  1089.                                                     /* Scan both source and destination drawers */
  1090.                                                     if ((num_enabled  = ScanTools(enabled_dir,  (struct List *)&enabled_list)) >= 0)
  1091.                                                     {    if ((num_disabled = ScanTools(disabled_dir, (struct List *)&disabled_list)) >= 0)
  1092.                                                         {    /* Reset the window's title */
  1093.                                                             SetWindowTitles(win, "WBStartup", (UBYTE *)-1L);
  1094.  
  1095.                                                             /* Update the gadgets */
  1096.                                                             sprintf(enabled_buf,  "%ld enabled tools",  num_enabled);
  1097.                                                             sprintf(disabled_buf, "%ld disabled tools", num_disabled);
  1098.  
  1099.                                                             GT_SetGadgetAttrs(enabled_lv,   win, NULL, GTLV_Labels, &enabled_list,    TAG_DONE);
  1100.                                                             GT_SetGadgetAttrs(enabled_str,  win, NULL, GTTX_Text,   &enabled_buf[0],  TAG_DONE);
  1101.                                                             GT_SetGadgetAttrs(disabled_lv,  win, NULL, GTLV_Labels, &disabled_list,   TAG_DONE);
  1102.                                                             GT_SetGadgetAttrs(disabled_str, win, NULL, GTTX_Text,   &disabled_buf[0], TAG_DONE);
  1103.  
  1104.                                                             ClearPointer(win);
  1105.  
  1106.                                                             /* Handle events */
  1107.                                                             MainLoop();
  1108.                                                         }
  1109.                                                     }
  1110.  
  1111.                                                     /* Clear the gadgets */
  1112.                                                     GT_SetGadgetAttrs(enabled_lv,  win, NULL, GTLV_Labels, ~0L, TAG_DONE);
  1113.                                                     GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
  1114.  
  1115.                                                     /* Free the scanned lists of tools */
  1116.                                                     FreeTools((struct List *)&disabled_list);
  1117.                                                     FreeTools((struct List *)&enabled_list);
  1118.  
  1119.                                                     /* Close the window */
  1120.                                                     CloseWindow(win);
  1121.                                                 }
  1122.                                                 /* Free the gadgets */
  1123.                                                 FreeGadgets(glist);
  1124.                                             }
  1125.                                             FreeVisualInfo(vi);
  1126.                                         }
  1127.                                         FreeScreenDrawInfo(scr, dri);
  1128.                                     }
  1129.                                     UnlockPubScreen(NULL, scr);
  1130.                                 }
  1131.                             }
  1132.                             /* Close the libraries */
  1133.                             CloseLibrary(IconBase);
  1134.                         }
  1135.                         CloseLibrary(WorkbenchBase);
  1136.                     }
  1137.                     CloseLibrary(GfxBase);
  1138.                 }
  1139.                 CloseLibrary(GadToolsBase);
  1140.             }
  1141.             CloseLibrary(IntuitionBase);
  1142.         }
  1143.         CloseLibrary(UtilityBase);
  1144.     }
  1145. }
  1146.